///////////////////////////////////////////////////////////////////////////////
//	FILENAME:	eTFileLinkUI.m 
//	SUMMARY:	Implementation of the FileLink UI
//	SUPERCLASS:	Object
//	INTERFACE:	None
//	PROTOCOLS:	<Inspectable>
//	AUTHOR:		Rohit Khare
//	COPYRIGHT:	(c) 1994 California Institure of Technology, eText Project
///////////////////////////////////////////////////////////////////////////////
//	IMPLEMENTATION COMMENTS
//		Read-only display of the filename and the link state.
//	Normally disabled exec string field (not editable, grayed-out, stringValue=
//	"open \"%s\""). When execSwitch fires, we setExec string, make the string
//	editable (and first responder). If execSwitch goes off, we run an alert
//	iff stringValue != default.
///////////////////////////////////////////////////////////////////////////////
//	HISTORY
//	08/06/94:	Added symbolic linking support.
//  07/03/94:	Created. Mimics RTFD file inclusions.
///////////////////////////////////////////////////////////////////////////////

#import "eTFileLink.h"
#define _defaultExecString "open \"%s\""

@implementation eTFileLinkUI
//    id	execField;
//    id	execSwitch;
//    id	filenameField;
//    id	filenameSwitch;
//    id	linkPanel;
//    id	linkView;
//	  id    theLink;
//	  id	symlinkSwitch;

- setAnnotation:newLink
{	
	if (newLink == theLink) return self;
	[super setAnnotation:newLink];	// this is an awkward naming of the "chain" 
	theLink = newLink;
	[filenameField setStringValue:[theLink componentName]];
	[filenameSwitch setState:[theLink isLinked]];
	[symlinkSwitch setEnabled:[theLink isLinked]];
	[symlinkSwitch setState:[theLink useSymlink]];
	if ([theLink isExecEnabled]) {
		// reset to reflect theLink's state
		[execSwitch setState:1];
		[execField setStringValue:[theLink execString]];
		[execField setEditable:YES];
		[execField setBackgroundGray:NX_WHITE];
	} else {	// NULL exec string
		// reset to baseline
		[execSwitch setState:0];
		[execField setStringValue:_defaultExecString];
		[execField setEditable:NO];
		[execField setBackgroundGray:NX_LTGRAY];
	}
	return self;
}
- enableExec:sender
{
	if ([sender state]) {	// up-transition
		// enable the field; prepare theLink
		[execField setEditable:YES];
		[execField setBackgroundGray:NX_WHITE];
		[theLink setExecString:_defaultExecString];
	} else {				// down-transition
		[theLink setExecEnabled:NO];
		[execField setEditable:NO];
		[execField setBackgroundGray:NX_LTGRAY];		
	}
    return self;
}
- setExec:sender
{
	[theLink setExecString:[sender stringValue]];
	[[theLink etDoc] touch];
    return self;
}
- forceSymlink:sender
{
	[theLink setSymlink:[sender state]];
	[[theLink etDoc] touch];
	return self;
}
///////////////////////////////////
+ new
{
	static eTFileLinkUI *ui = nil;
	
	if (!ui) {
		ui = [[eTFileLinkUI alloc] init];
	}
	return ui;
}
- init
{
	char        buf[MAXPATHLEN];
	NXBundle   *bundle;

	[super init];
	bundle = [NXBundle bundleForClass:[self class]];
	if ( [bundle getPath:buf forResource:"eTFileLinkUI" ofType:"nib"] ) {
		[NXApp loadNibFile:buf owner:self withNames:NO];
	} else {
		NXLogError("NIB not found: eTFileLinkUI");
	}
	linkView = [linkPanel contentView];
	return self;
}
- free {return self;}
///////////////////////////////////
#define PROP "File Properties"

- (const NXAtom *) types
{
	static NXAtom *types = NULL;
	
	if (!types) {
		int i;
		const NXAtom *superTypes = [super types];
		
		for(i=0;superTypes[i];i++);
		i++; // make room for terminating NULL
		i++; // make room for our type
		types = malloc(i * sizeof(NXAtom));
		types[0] = NXUniqueString(PROP);
		for(i=0;superTypes[i];i++) types[i+1] = superTypes[i];
		types[i+1] = NULL;
	}
	return types;
}
- (const char *) inspectorTitle
{
	return NXUniqueString("File");
}
- resignInspector: (View *) oldInspector ofType: (const char *) type
{
	if (oldInspector != linkView)
		[super resignInspector:oldInspector ofType:type];
	return self;
}
- activateInspector: (View *) newInspector ofType: (const char *) type
{
	if (newInspector != linkView)
		[super activateInspector:newInspector ofType:type];
	return self;
}
- inspectorForType:(const char *) type
{
	if(!strcmp(type,NXUniqueString(PROP)))
		return linkView;
	return [super inspectorForType:type];
}
@end
